package com.texeljoy.camera

import android.Manifest
import android.content.pm.PackageManager
import android.graphics.Color
import android.graphics.ImageFormat
import android.graphics.PorterDuff
import android.hardware.Camera
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.SurfaceHolder
import androidx.appcompat.app.AppCompatActivity
import com.texeljoy.hteffect.HTEffect
import com.texeljoy.hteffect.model.HTFormatEnum
import com.texeljoy.hteffect.model.HTItemEnum
import com.texeljoy.hteffect.model.HTRotationEnum
import kotlinx.android.synthetic.main.activity_main.cameraPreSurface
import kotlinx.android.synthetic.main.activity_main.openGlSurface

class MainActivity : AppCompatActivity(), Camera.PreviewCallback {
    companion object {
        private const val TAG = "MainActivity"
    }

    private var mCamera: Camera? = null
    // 设定默认的预览宽高
    private var mPreviewWidth = 1280 // 1920
    private var mPreviewHeight = 720 // 1280

    private var mBuffer: ByteArray? = null

    private lateinit var mSurfaceHolder: SurfaceHolder

    var hasInit = false

    protected var initStatus = false

    protected var authStatus = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //! 提示摄像头权限获取，TODO：目前获取权限后，需要退到后台，再打开才能生效，而非立即生效
        checkPermission()

        cameraPreSurface.holder.addCallback(object : SurfaceHolder.Callback {
            override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {

            }

            override fun surfaceDestroyed(holder: SurfaceHolder) {
                releaseCamera()
            }

            override fun surfaceCreated(holder: SurfaceHolder) {
                mSurfaceHolder = holder
                initCamera()
            }
        })

        HTEffect.shareInstance()
            .initHTEffect(this, "<YOUR_APP_ID>", object : HTEffect.InitCallback {
                override fun onInitSuccess() {
                    hasInit = true
                }

                override fun onInitFailure() {}
            })
    }

    private fun initCamera() {
        try {
            mCamera = openCamera()

            mCamera?.apply {
                var params: Camera.Parameters = parameters
                val sizes = params.supportedPreviewSizes
                if (sizes != null) {
                    /* Select the size that fits surface considering maximum size allowed */
                    calculateCameraFrameSize(sizes, mPreviewWidth, mPreviewHeight)
                }
                params.previewFormat = ImageFormat.NV21
                params.setPreviewSize(mPreviewWidth, mPreviewHeight)
                Log.d(TAG, "Set preview size to $mPreviewWidth x $mPreviewHeight")

                parameters = params

                openGlSurface.setYuvDataSize(mPreviewWidth, mPreviewHeight)

                var size = mPreviewWidth * mPreviewHeight
                size = size * 3 / 2
//                size = size * ImageFormat.getBitsPerPixel(params.previewFormat) / 8
                mBuffer = ByteArray(size)

                addCallbackBuffer(mBuffer)
                setPreviewCallbackWithBuffer(this@MainActivity)

                setPreviewDisplay(mSurfaceHolder)

                startPreview()//开始预览
            }
        } catch (e: Exception) {
            e.message?.let { Log.w(TAG, it) }
        }
    }

    override fun onPreviewFrame(data: ByteArray, camera: Camera?) {

        if (!initStatus) {
            Log.e("初始化:", "------")
//            HTEffect.shareInstance().releaseBufferRenderer()
            Log.e("width:", mPreviewWidth.toString() + "px")
            Log.e("height:", mPreviewHeight.toString() + "px")
            HTEffect.shareInstance().setRenderEnable(true);
            initStatus = HTEffect.shareInstance().initBufferRenderer(
                HTFormatEnum.HTFormatNV21,
                mPreviewWidth,
                mPreviewHeight,
                HTRotationEnum.HTRotationClockwise270,
                true,
                5
            )
        }

        HTEffect.shareInstance().setARItem(0, "ht_sticker_effect_smallcat")
//        HTEffect.shareInstance().setARItem(4, "ht_3d_effect_tiger");
        HTEffect.shareInstance().processBuffer(data)
//        val results = HTEffect.shareInstance().faceDetectionReport;
//        Log.i("face num: ", results.size.toString());

        openGlSurface.feedData(data, 2)
        camera?.addCallbackBuffer(mBuffer)
    }

    /**
     * 打开Camera
     */
    private fun openCamera(): Camera? {
        Log.d(TAG, "Trying to open camera with old open()")
        var camera: Camera? = null
        try {
            camera = Camera.open(1)
        } catch (e: Exception) {
            Log.w(TAG, "Camera is not available (in use or does not exist): ${e.message}")
        }

        if (camera == null) {
            var connected = false
            for (camIdx in 0 until Camera.getNumberOfCameras()) {
                Log.d(TAG, "Trying to open camera with new open(" + Integer.valueOf(camIdx) + ")")
                try {
                    camera = Camera.open(camIdx)
                    connected = true
                } catch (e: RuntimeException) {
                    Log.w(TAG, "Camera #$camIdx failed to open: ${e.message}")
                }

                if (connected) break
            }
        }

        return camera
    }

    /**
     * 释放Camera资源
     */
    private fun releaseCamera() {
        mCamera?.apply {
            stopPreview()
            setPreviewCallback(null)
            release()
        }
        mCamera = null
    }

    private fun calculateCameraFrameSize(supportedSizes: List<*>, maxAllowedWidth: Int, maxAllowedHeight: Int) {
        var calcWidth = 0
        var calcHeight = 0

        for (size in supportedSizes) {
            val cameraSize = size as Camera.Size
            val width = cameraSize.width
            val height = cameraSize.height

            if (width <= maxAllowedWidth && height <= maxAllowedHeight) {
                if (width >= calcWidth && height >= calcHeight) {
                    // 找到临近的像素大小
                    calcWidth = width
                    calcHeight = height
                }
            }
        }

        mPreviewWidth = calcWidth
        mPreviewHeight = calcHeight
    }

    override fun onDestroy() {
        releaseCamera()
        super.onDestroy()
    }

    private fun checkPermission(): Boolean {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(
                Manifest.permission.WRITE_EXTERNAL_STORAGE
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            requestPermissions(
                arrayOf(
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE,
                    Manifest.permission.CAMERA
                ), 1
            )
        }
        return false
    }
}
